
/*
 * WizardConceptLib.java
 *
 * Dialog which can be used to add a new-preannotated concept dictionary into
 * system.
 *
 * Created on Jan 18, 2010, 7:38:34 PM
 */

package UserInterface.addNewDict;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.beans.PropertyChangeSupport;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Vector;


/**
 * This is a dalog which can add a new pre-annotated concept dictionary into
 * the list of dictionaries.
 * 
 * To add a new dictionary, you need to know its separator first. And then
 * use this separator to split each line in this dictionary file. Only if there 
 * are 2 column in the line, it's a valid dictionary entry.
 * 
 * The first column left to the separator is the regex content; the right column
 * is its matched comment, which usually used to mark the category of your found
 * concepts.
 *
 *
 * @author  Jianwei "Chris" Leng, Division of Epidemiology, Medicine School, University of Utah
 * @since   Java 1.5 & Mar 1, 2010
 * @version 2.0 rewrite on Sep 10, 2010 by Jianwei "Chris" Leng
 *
 */

public class WizardConceptLib extends javax.swing.JFrame {

    // variables
    protected PropertyChangeSupport propertyChange = new PropertyChangeSupport(this);
    private java.awt.Frame FATHER_WINDOW_HANDLE;
    private int FLAG_PANEL = 0;
    
    /** 
     * value of integer used to show how many entries in the pre-annotated 
     * concept dictioary you designated; this variable will be given a value in 
     * method of <code>evaluateChanges_beforeSaving()</code> in this class.*/
    private int lines = -1;

    /**
     * In step 3, while system is busy in processing data to envalute new
     * dictionary by given informations, set this flag to true for flash text
     * display on screen of step 3 for method <code>step3_showThreadBusy()</code>.
     */
    private boolean systemBusy = false;

    /**
     * This is a variable for system to remember the thread which used to 
     * display busy status of step 3.
     * 
     * In step 3, while system is busy in processing data to envalute new
     * dictionary by given informations, set this flag to true for flash text
     * display on screen of step 3 for method <code>step3_showThreadBusy()</code>.
     */
    private Thread busyThread = null;
    protected UserInterface.GUI __gui;
    /** Construction: creates new form WizardConceptLib */
    public WizardConceptLib(java.awt.Frame _FATHER_WINDOW_HANDLE, UserInterface.GUI _gui) {

        FLAG_PANEL = 1;
        FATHER_WINDOW_HANDLE = _FATHER_WINDOW_HANDLE;
        __gui = _gui;

        // init and set dialog location
        initComponents();
        setLocation();

        // init buttons
        jButton_back.setEnabled(false);
        jButton_back.setEnabled(false);
        jPanel_CardLayout.removeAll();
        jPanel_CardLayout.add(jPanel_Introduction, "1");
        jPanel_CardLayout.repaint();

    }

    
    /**Set the location at the middle of its faterwindow.*/
    private void setLocation(){

        // set frame size of this dialog
        this.setPreferredSize(new Dimension(618,380));

        // valid check
        if( FATHER_WINDOW_HANDLE == null )
            return;

        // calculate the location to set this dialog at the middle of parent
        // dialog
        int parentX = FATHER_WINDOW_HANDLE.getX(), 
            parentY = FATHER_WINDOW_HANDLE.getY();
        int parentWidth = FATHER_WINDOW_HANDLE.getWidth(),
            parentHeight = FATHER_WINDOW_HANDLE.getHeight();

        int width = this.getWidth(), height = this.getHeight();
        int x = parentX + (int)(parentWidth  -  width)/2,
            y = parentY + (int)(parentHeight - height)/2;

        // set location of this dialog
        this.setLocation(x, y);
    }

    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jFileChooser1 = new javax.swing.JFileChooser();
        jPanel_CardLayout = new javax.swing.JPanel();
        jPanel_Introduction = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        jLabel22 = new javax.swing.JLabel();
        jLabel24 = new javax.swing.JLabel();
        jPanel_choosefile = new UserInterface.addNewDict.JPanel_dnd(this);
        jLabel3 = new javax.swing.JLabel();
        jTextField_ConceptLib = new JTextField_dnd(this);
        jLabel6 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        jLabel21 = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jLabel23 = new javax.swing.JLabel();
        jLabel25 = new javax.swing.JLabel();
        jTextField_Separator = new javax.swing.JTextField();
        jPanel_verifyer = new javax.swing.JPanel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel_right_icon = new javax.swing.JLabel();
        jLabel_step3_title = new javax.swing.JLabel();
        jLabel_error_msg = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel9 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jPanel_saved = new javax.swing.JPanel();
        jLabel13 = new javax.swing.JLabel();
        jLabel_step4_title = new javax.swing.JLabel();
        jLabel26 = new javax.swing.JLabel();
        jPanel_Buttons = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jButton_back = new javax.swing.JButton();
        jButton_next = new javax.swing.JButton();
        jButton_cancel = new javax.swing.JButton();

        jFileChooser1.setSelectedFiles(null);

        setTitle("Wizard - [ Add new pre-annotated concept dictionary]");
        setAlwaysOnTop(true);
        setBackground(new java.awt.Color(237, 237, 237));
        setMinimumSize(new java.awt.Dimension(618, 347));
        setPreferredSize(new java.awt.Dimension(600, 380));
        setResizable(false);
        setSize(new java.awt.Dimension(618, 380));
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        jPanel_CardLayout.setMaximumSize(new java.awt.Dimension(558, 305));
        jPanel_CardLayout.setLayout(new java.awt.CardLayout());

        jPanel_Introduction.setBackground(new java.awt.Color(255, 255, 255));
        jPanel_Introduction.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
        jPanel_Introduction.setFont(new java.awt.Font("Segoe UI Light", 1, 14));
        jPanel_Introduction.setMaximumSize(new java.awt.Dimension(558, 305));
        jPanel_Introduction.setRequestFocusEnabled(false);
        jPanel_Introduction.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/UserInterface/addNewDict/gears.jpg"))); // NOI18N
        jPanel_Introduction.add(jLabel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(200, 10, -1, -1));

        jLabel2.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel2.setText("<html>This is a wizard which will help you to choose a new dictionary.</html>");
        jPanel_Introduction.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 180, 220, 40));

        jLabel18.setFont(new java.awt.Font("Calibri", 1, 18));
        jLabel18.setText("Add New Pre-Annotated Concept Dictionary");
        jPanel_Introduction.add(jLabel18, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 20, -1, -1));

        jLabel22.setFont(new java.awt.Font("Calibri", 1, 14));
        jLabel22.setText("Introduction");
        jPanel_Introduction.add(jLabel22, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 60, -1, -1));

        jLabel24.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel24.setText("<html>Before you start to extract concepts from raw text files, such as clinical notes, you need to designate one or more pre-annotated concept dictionary to eHOST. </html>");
        jPanel_Introduction.add(jLabel24, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 80, 220, 90));

        jPanel_CardLayout.add(jPanel_Introduction, "card2");

        jPanel_choosefile.setBackground(new java.awt.Color(254, 254, 254));
        jPanel_choosefile.setMaximumSize(new java.awt.Dimension(558, 305));
        jPanel_choosefile.setPreferredSize(new java.awt.Dimension(558, 305));
        jPanel_choosefile.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel3.setFont(new java.awt.Font("Calibri", 1, 18));
        jLabel3.setText("Select A New Pre-annotated Concept Dictionary");
        jPanel_choosefile.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(24, 20, -1, -1));

        jTextField_ConceptLib.setFont(new java.awt.Font("Calibri", 0, 14));
        jPanel_choosefile.add(jTextField_ConceptLib, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 110, 290, -1));

        jLabel6.setFont(new java.awt.Font("Calibri", 1, 18));
        jLabel6.setForeground(new java.awt.Color(204, 204, 204));
        jLabel6.setText("Drop Your Dictionary Here");
        jPanel_choosefile.add(jLabel6, new org.netbeans.lib.awtextra.AbsoluteConstraints(50, 290, -1, -1));

        jLabel17.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel17.setText("You can select a dictionary by clicking \"Choose\" button or just drag-drop your dictionary to this dialog.");
        jPanel_choosefile.add(jLabel17, new org.netbeans.lib.awtextra.AbsoluteConstraints(24, 45, -1, -1));
        jPanel_choosefile.add(jLabel19, new org.netbeans.lib.awtextra.AbsoluteConstraints(462, 95, -1, 149));

        jLabel20.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel20.setText("Pre-annotate directory:");
        jPanel_choosefile.add(jLabel20, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 90, -1, -1));

        jLabel21.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel21.setForeground(new java.awt.Color(204, 0, 0));
        jLabel21.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/markerror.png"))); // NOI18N
        jLabel21.setText("jLabel21");
        jPanel_choosefile.add(jLabel21, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 260, 290, 50));

        jButton1.setText("Choose");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel_choosefile.add(jButton1, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 140, 80, -1));

        jLabel23.setIcon(new javax.swing.ImageIcon(getClass().getResource("/UserInterface/addNewDict/dropfile.png"))); // NOI18N
        jPanel_choosefile.add(jLabel23, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 80, -1, -1));

        jLabel25.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel25.setText("Current Separator:");
        jPanel_choosefile.add(jLabel25, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 180, -1, -1));

        jTextField_Separator.setFont(new java.awt.Font("Calibri", 0, 14));
        jTextField_Separator.setText("jTextField3");
        jPanel_choosefile.add(jTextField_Separator, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 200, 290, -1));

        jPanel_CardLayout.add(jPanel_choosefile, "card3");

        jPanel_verifyer.setBackground(new java.awt.Color(254, 254, 254));
        jPanel_verifyer.setMaximumSize(new java.awt.Dimension(558, 305));
        jPanel_verifyer.setPreferredSize(new java.awt.Dimension(558, 305));
        jPanel_verifyer.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
        jPanel_verifyer.add(jLabel10, new org.netbeans.lib.awtextra.AbsoluteConstraints(34, 134, -1, -1));
        jPanel_verifyer.add(jLabel11, new org.netbeans.lib.awtextra.AbsoluteConstraints(34, 157, -1, -1));

        jLabel_right_icon.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/mark1.png"))); // NOI18N
        jPanel_verifyer.add(jLabel_right_icon, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 10, -1, -1));

        jLabel_step3_title.setFont(new java.awt.Font("Calibri", 1, 18));
        jLabel_step3_title.setText("Evaluate Changes before Saving");
        jPanel_verifyer.add(jLabel_step3_title, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 20, -1, -1));

        jLabel_error_msg.setFont(new java.awt.Font("Calibri", 1, 14));
        jLabel_error_msg.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/markerror.png"))); // NOI18N
        jLabel_error_msg.setText("jLabel16");
        jPanel_verifyer.add(jLabel_error_msg, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 310, -1, -1));

        jPanel1.setBackground(new java.awt.Color(254, 254, 254));
        jPanel1.setLayout(new java.awt.GridLayout(3, 0, 0, 2));

        jLabel7.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel7.setForeground(new java.awt.Color(0, 0, 153));
        jLabel7.setText("jLabel7");
        jPanel1.add(jLabel7);

        jLabel8.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel8.setForeground(new java.awt.Color(0, 0, 153));
        jLabel8.setText("jLabel8");
        jPanel1.add(jLabel8);

        jLabel9.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel9.setForeground(new java.awt.Color(0, 0, 153));
        jLabel9.setText("jLabel9");
        jPanel1.add(jLabel9);

        jPanel_verifyer.add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 210, 570, 60));

        jLabel5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/UserInterface/addNewDict/verify_dict.png"))); // NOI18N
        jPanel_verifyer.add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 10, -1, -1));

        jPanel_CardLayout.add(jPanel_verifyer, "card4");

        jPanel_saved.setBackground(new java.awt.Color(254, 254, 254));
        jPanel_saved.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel13.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/BackUp.png"))); // NOI18N
        jPanel_saved.add(jLabel13, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 100, -1, -1));

        jLabel_step4_title.setFont(new java.awt.Font("Calibri", 1, 18)); // NOI18N
        jLabel_step4_title.setText("Saving Changes for Adding a New Dictionary ...");
        jPanel_saved.add(jLabel_step4_title, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 20, -1, -1));

        jLabel26.setFont(new java.awt.Font("Calibri", 0, 14));
        jLabel26.setText("Please click button of \"DONE\" to leave this dialog.");
        jPanel_saved.add(jLabel26, new org.netbeans.lib.awtextra.AbsoluteConstraints(30, 50, -1, -1));

        jPanel_CardLayout.add(jPanel_saved, "card5");

        getContentPane().add(jPanel_CardLayout, java.awt.BorderLayout.CENTER);

        jPanel_Buttons.setBackground(new java.awt.Color(222, 222, 222));
        jPanel_Buttons.setLayout(new java.awt.BorderLayout());

        jPanel2.setBackground(new java.awt.Color(222, 222, 222));
        jPanel2.setLayout(new java.awt.GridBagLayout());

        jButton_back.setText("Back");
        jButton_back.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_backActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 4);
        jPanel2.add(jButton_back, gridBagConstraints);

        jButton_next.setText("Next");
        jButton_next.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_nextActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 4);
        jPanel2.add(jButton_next, gridBagConstraints);

        jButton_cancel.setText("Cancel");
        jButton_cancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton_cancelActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(2, 0, 2, 0);
        jPanel2.add(jButton_cancel, gridBagConstraints);

        jPanel_Buttons.add(jPanel2, java.awt.BorderLayout.EAST);

        getContentPane().add(jPanel_Buttons, java.awt.BorderLayout.SOUTH);

        pack();
    }// </editor-fold>//GEN-END:initComponents


    
    /**
     * This is the event handler for clinking mouse on button of "next".
     *
     * @param   evt
     *          System mouse action event.
     */
    private void jButton_nextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton_nextActionPerformed
        
        switch( FLAG_PANEL ){

            case 1:
                jButton_back.setEnabled(true);
                jButton_back.enable();
                jPanel_CardLayout.removeAll();
                jPanel_CardLayout.add(jPanel_choosefile, "2");
                jPanel_choosefile.setVisible(true);

                jTextField_ConceptLib.setText( "" );
                jTextField_Separator.setText( "<--->" );

                FLAG_PANEL = 2;
                jPanel_CardLayout.repaint();
                jLabel21.setVisible(false);
                jLabel21.setIcon( jLabel_error_msg.getIcon() );
                break;


            case 2: // jump to the page to evaluate the dictrionary before saving
                if (!step2check()) break;

                jPanel_CardLayout.removeAll();
                jPanel_CardLayout.add(jPanel_verifyer, "3");
                jPanel_verifyer.setVisible(true);
                jLabel7.setText(null);jLabel8.setText(null);
                jLabel9.setText(null);
                jLabel7.setIcon( null );jLabel8.setIcon( null );
                jLabel9.setIcon( null );

                jLabel10.setVisible(false);
                jLabel11.setVisible(false);
                jLabel_right_icon.setVisible(false);
                jLabel_error_msg.setVisible(false);
                FLAG_PANEL = 3;

                this.jButton_next.setEnabled(false);
                
                jPanel_CardLayout.repaint();

                step3_showThreadBusy_start();

                // start new threads to evalute the dictionary so we do not 
                // need to froze gui to waiting for response.
                new Thread(){
                    @Override
                    public void run(){
                        evaluateChanges_beforeSaving();
                    }}.start();

                


                break;
            case 3:
                jPanel_CardLayout.removeAll();
                jPanel_CardLayout.add(jPanel_saved, "4");
                jPanel_CardLayout.validate();

                jButton_back.setVisible( false );
                jButton_next.setVisible( false );
                
                FLAG_PANEL = 4;
                jPanel_CardLayout.repaint();
                this.jLabel_step4_title.setText("Saving Changes for Adding a New Dictionary ...");


                step4_savingChanges(this.lines);

                break;
            case 4: //this.setVisible(false);

                FATHER_WINDOW_HANDLE.setVisible(true);
                FATHER_WINDOW_HANDLE.setEnabled(true);
                this.dispose();
                break;
        }

    }//GEN-LAST:event_jButton_nextActionPerformed


    /**
     * Make sure textfileds of filename and separator are not empty before we
     * enter the tab of next step.
     *
     * Before we enter step 3 to check this dictionary, we need to check the
     * textfield to make sure they are not empty. If filename or separator of
     * the dictionary is empty, we stop in current step and give user some text
     * message on same dialog as warnings.
     *
     * @return      true
     *              While it past the basic validity check, return true;
     * 
     *              false
     *              If current filename and seperator could not pass the basic
     *              validity check.
     *
     */
    private boolean step2check(){

        // get filename and separator from the component of this dialog
        String conceptLib = jTextField_ConceptLib.getText().trim();
        String separator = jTextField_Separator.getText();

        // **** DEBUG; use to echo filename and separator
        //System.out.println("----------------" + conceptLib + "=======" + separator );
        
        // check the filename of pre-annotated concept dictionary,
        // make sure it's not empty
        if ( (conceptLib == null)||(conceptLib.length() < 1)){
            jLabel21.setText( "<html>Note: You must choose a file before you goto next step!!!</html>" );
            jLabel21.setVisible(true);
            Toolkit.getDefaultToolkit().beep();
            return false;
        }

        // check the separator of pre-annotated concept dictionary, make sure it's
        // not empty
        if ( (separator == null)||(separator.length() < 1)){
            jLabel21.setText( "<html>Note: You must enter a separator for this 2 colums text file!!!</html>" );
            jLabel21.setVisible(true);
            Toolkit.getDefaultToolkit().beep();
            return false;
        }
        return true;
    }



    /**
     * Verify step to designated pre-annotated concept dictionary. We need to
     * verified this dictionary by given path name and designated separator.
     *
     * If success, go to next step "save"; Otherwise, frozen GUI on current
     * stage and show text on dialog as warnings.
     *
     */
    private void evaluateChanges_beforeSaving()
    {

        // ##1##  get filename and separator from textfile components on the dialog
        String conceptLib = jTextField_ConceptLib.getText().trim();
        String separator = jTextField_Separator.getText();
        
        // ##2.1##  if empty value of filename of the dictionary
        if ( ( conceptLib == null ) ||(conceptLib.length() < 1) ){
            jLabel7.setText("This is not a valid file name - [" + conceptLib +"]");
            jButton_next.setEnabled(false);
            jLabel10.setIcon( jLabel_error_msg.getIcon() );
            jLabel10.setVisible(true);
            jLabel_error_msg.setText("Please go back to previous step to modify your input");
            jLabel_error_msg.setVisible(true);
            Toolkit.getDefaultToolkit().beep();
            step3_showThreadBusy_end();
            return;
        }

        // ##2.2##  if file not existed
        boolean fexist = commons.Filesys.checkFilesExists( conceptLib );
        if(!fexist){
            jLabel7.setText("This file do not exist! - [" + conceptLib +"]");            
            jLabel7.setIcon( jLabel_error_msg.getIcon() ); // set failure icon
            jLabel_error_msg.setText("Please go back to previous step to modify your input");
            jLabel_error_msg.setVisible(true);

            jButton_next.setEnabled(false);
            Toolkit.getDefaultToolkit().beep();
            step3_showThreadBusy_end();
            return;
        }

        // ##2.3##  if file existed, set echo on dialog
        jLabel7.setText("File validity checked. - " + conceptLib  );
        jLabel7.setIcon( jLabel_right_icon.getIcon() ); // success icon
        

        // ##2.4##  make sure there are more than 1 row of valid entry in this
        //          pre-annotated concept dicionary
        lines = validityCheck_ConceptDictionary( conceptLib, separator );
        if ( lines < 1 ){
                jLabel8.setText("No valid concepts found by separator - [" + separator +"]");
                jButton_next.setEnabled(false);
                jLabel8.setIcon( jLabel_error_msg.getIcon() );
                //jLabel11.setVisible(true);
                jLabel_error_msg.setText("Please go back to previous step to modify your input");
                jLabel_error_msg.setVisible(true);
                Toolkit.getDefaultToolkit().beep();
                step3_showThreadBusy_end();
                return;
        }


        // ##2.5##  have more than 1 valid entry in this dictionary, echo
        //          some msg on dialog.
        String echo_separator = separator.replaceAll("<", "&#60");
        echo_separator = echo_separator.replaceAll(">", "&#62");
        
        jLabel8.setText( "<html><font color=red>"
                + String.valueOf(lines)
                + "</font>"
                + " valid pre-annotated terms found in lib by separator - [<font color=red>"
                + echo_separator
                + "</font>]</html>");
        jLabel8.setIcon( jLabel_right_icon.getIcon() );
        //jLabel11.setVisible(true);

        
        jLabel9.setText( "Ready to save it on next step." );
        jLabel9.setIcon( jLabel_right_icon.getIcon() );
        //jLabel_right_icon.setVisible(true);

        //jButton_back.setVisible(false);
        jButton_cancel.setEnabled(true);
        jButton_next.setText("Save It");
        jButton_next.setEnabled(true);
        FLAG_PANEL = 3;

        step3_showThreadBusy_end();

    }


    /**
     * We need to save changes of adding new pre-annotated concept dictionary
     * after user clicked button after step 3
     *
     * @param   lines
     *          Amount of entries in the pre-annotated concept dictionary you
     *          just designated.
     */
    private void step4_savingChanges(int amount_of_enties){

        String conceptLib = this.jTextField_ConceptLib.getText().trim();
        String separator = this.jTextField_Separator.getText().trim();

        // ##3## if everything is good, record them
        env.Parameters.CONCEPT_LIB = conceptLib;  // this maybe a invalid parameter
        env.Parameters.CONCEPT_LIB_SEPARTOR = separator ;
        /** @para absouteFilename - file name with absolute path
        * @para weight - if same all will be 0, otherwise big number
        * means heavy weight
        * @para description
        * @para separator
        * @para number_of_valid_entries
        */
        int weight = env.Parameters.PREANNOTATED_CONCEPT_DICTIONARIES.size();
        if( env.Parameters.PRE_ANNOTATED_CONCEPT_DICTIONARIES_HAVE_DIFFERENT_WEIGHT )
                weight++;
        else weight=0;
        Object[] o = { conceptLib,
            String.valueOf(weight),
            "Pre-annotated concept dictionary.",
            separator,
            String.valueOf(amount_of_enties)};
        env.Parameters.PREANNOTATED_CONCEPT_DICTIONARIES.add(o);

        config.project.ProjectConf projectconf = new config.project.ProjectConf(
                    env.Parameters.WorkSpace.CurrentProject);
        projectconf.saveConfigure();

        // save annotation classnames which found in this pre-annotation
        // concept dictionary
        saveAnnotationClassnames();

        this.jLabel_step4_title.setText("Changed Saved.");
        this.jButton_cancel.setText("DONE");

    }

    
    /**Save annotation classnames which found in this pre-annotation concept
     * dictionary. */
    private void saveAnnotationClassnames(){
        // new thread as we want to save some time;
        new Thread(){
            @Override
            public void run(){
                // all annotation classname gathered for current just
                // selected pre-annotation concept dictionary.
                GatherAnnotationClassnames gather = new GatherAnnotationClassnames();
                Vector<ResultEditor.AnnotationClasses.AnnotatedClass> annotationclassnames  = gather.getAllElements();

                // save into working set
                ResultEditor.AnnotationClasses.Depot depot =
                        new ResultEditor.AnnotationClasses.Depot();
                depot.addElements(annotationclassnames);

                // save changes into disk
                depot.saveAnnotationClassnamesToConfigureFile();

                __gui.showAnnotationCategoriesInTreeView_refresh();
            }
        }.start();
    }


    
    private void jButton_backActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton_backActionPerformed
        // TODO add your handling code here:
        switch( FLAG_PANEL ){
            case 2:
                jButton_back.setEnabled(false);
                jButton_back.disable();
                jPanel_CardLayout.removeAll();
                jPanel_CardLayout.add(jPanel_Introduction, "1");
                jButton_cancel.setEnabled(true);
                FLAG_PANEL = 1;
                jPanel_CardLayout.repaint();
                break;
           case 3:
                jButton_back.setEnabled(true);
                jPanel_CardLayout.removeAll();
                jPanel_CardLayout.add(jPanel_choosefile, "2");
                FLAG_PANEL = 2;
                jLabel21.setVisible(false);
                jButton_next.setEnabled(true);
                jButton_next.setText("Next");
                jButton_cancel.setEnabled(true);
                jPanel_CardLayout.repaint();
                break;
        }
    }//GEN-LAST:event_jButton_backActionPerformed


    
    private void jButton_cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton_cancelActionPerformed
                   
        FATHER_WINDOW_HANDLE.setVisible(true);
        FATHER_WINDOW_HANDLE.setEnabled(true);
        this.dispose();

    }//GEN-LAST:event_jButton_cancelActionPerformed


    
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        int re = jFileChooser1.showDialog(this, "Set");
        //jLabel8.setText(String.valueOf(re));
        if (re == 0){
            //jFileChooser1.setFileSelectionMode(1);
            String filename = jFileChooser1.getSelectedFile().toString();
            jTextField_ConceptLib.setText(filename);
        }
    }//GEN-LAST:event_jButton1ActionPerformed

    
    /**Show file name of the dictionary on text field.*/
    public void setDictionaryName(File f){
        jTextField_ConceptLib.setText(null);
        if (f!=null){
            jTextField_ConceptLib.setText(f.getAbsolutePath());
        }
    }

    
    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
            // TODO add your handling code here:
            FATHER_WINDOW_HANDLE.setVisible(true);
            FATHER_WINDOW_HANDLE.setEnabled(true);            
            //FATHER_WINDOW_HANDLE.setStartAnalysisVisible();
    }//GEN-LAST:event_formWindowClosing
    
    
    @SuppressWarnings("static-access")
    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
            // TODO add your handling code here:
            FATHER_WINDOW_HANDLE.setVisible(true);
            FATHER_WINDOW_HANDLE.setEnabled(true);
            UserInterface.Setting f = (UserInterface.Setting)FATHER_WINDOW_HANDLE;
            f.Show_dictionaries_on_list();
    }//GEN-LAST:event_formWindowClosed

    
    /**Check validity of an appointted pre-annotated concept dictionary with
     * assigned separator.
     * @return is the amount of all valid records after being separated */
    private int validityCheck_ConceptDictionary(String _absoluteFilename, String _separator ){
        
        int count = 0;
        String[] str;
        try{
            // preparation for annotation classname gather
            GatherAnnotationClassnames gather = new GatherAnnotationClassnames();
            gather.removeAllElements();

            // preparation for file reading
            BufferedReader f = new BufferedReader( new FileReader( _absoluteFilename ));
            String line = f.readLine();

            // handle each line in this file (pre-annotation dictionary file)
            while( line != null ){
                str = line.split( _separator , 2 );
                if ( str.length == 2 ){
                    gather.addElement(str[1], _absoluteFilename );
                    count++;
                }
                line = f.readLine();
            }
            f.close();

            saveAnnotationClassnames();
            
        }catch(Exception e){
            System.out.println(e);
        }
        return count;
    }


    /**while checking the validity of concept dictionary, all collected classname
     * will be stored into here depot of classname and save into disk
     */
    static class Classname{
        static Vector<String> classnames = new Vector<String>();
        public static void clear(){
            classnames.clear();
        }

        public static void add(String _classname){
            if(_classname==null)
                return;

            if(!exists(_classname))
                classnames.add(_classname.trim());
        }

        public static boolean exists(String _classname){
            try{
                if(_classname==null)
                    return true;

                for(String classname:classnames)
                {
                    if(classname==null)
                        continue;
                    if(classname.trim().length()<1)
                        continue;
                    if(classname.trim().compareTo(_classname.trim())==0)
                        return true;
                }

                return false;
            }catch(Exception ex){
                return true;
            }


        }
    }

    /**
     * Flash-display the title(<code>jlabel_step3_title</code>)to indicate
     * system is busy to handling some data.
     */
    private void step3_showThreadBusy_start(){
        this.systemBusy = true;
        if( busyThread != null )
            busyThread.interrupt();
        step3_showThreadBusy();
    }
    private void step3_showThreadBusy_end(){
        this.systemBusy = false;
        if( busyThread != null )
            busyThread.interrupt();
    }
    private void step3_showThreadBusy(){

       busyThread = new Thread(){
            @Override
            public void run(){

                while( WizardConceptLib.this.systemBusy ) {
                    
                    jLabel_step3_title.setText("Evaluate Changes before Saving: ...");
                    jPanel_CardLayout.repaint();

                    try
                    {
                        Thread.sleep(300);
                    }
                    catch(Exception e)
                    {
                        System.out.println("Error 1008131658: error");
                    }

                    jLabel_step3_title.setText("Evaluate Changes before Saving: ... ...");
                    jPanel_CardLayout.repaint();

                    try
                    {
                        Thread.sleep(300);
                    }
                    catch(Exception e)
                    {
                        System.out.println("Error 1008131658: error");
                    }

                    jLabel_step3_title.setText("Evaluate Changes before Saving:");
                    jPanel_CardLayout.repaint();
                    
                    try
                    {
                        Thread.sleep(300);
                    }
                    catch(Exception e)
                    {
                        System.out.println("Error 1008131658: error");
                    }

                }
            }};

      busyThread.start();
    }

    public void step3_showThreadBusy_Instance(){

    }
    

    /**
     * @param args the command line arguments
     */
    /*public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new WizardConceptLib().setVisible(true);
            }
        });
    }*/

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton_back;
    private javax.swing.JButton jButton_cancel;
    private javax.swing.JButton jButton_next;
    private javax.swing.JFileChooser jFileChooser1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel21;
    private javax.swing.JLabel jLabel22;
    private javax.swing.JLabel jLabel23;
    private javax.swing.JLabel jLabel24;
    private javax.swing.JLabel jLabel25;
    private javax.swing.JLabel jLabel26;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JLabel jLabel_error_msg;
    private javax.swing.JLabel jLabel_right_icon;
    private javax.swing.JLabel jLabel_step3_title;
    private javax.swing.JLabel jLabel_step4_title;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel_Buttons;
    private javax.swing.JPanel jPanel_CardLayout;
    private javax.swing.JPanel jPanel_Introduction;
    private javax.swing.JPanel jPanel_choosefile;
    private javax.swing.JPanel jPanel_saved;
    private javax.swing.JPanel jPanel_verifyer;
    private javax.swing.JTextField jTextField_ConceptLib;
    private javax.swing.JTextField jTextField_Separator;
    // End of variables declaration//GEN-END:variables

    public void dragEnter(DropTargetDragEvent dtde) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void dragOver(DropTargetDragEvent dtde) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void dragExit(DropTargetEvent dte) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void drop(DropTargetDropEvent dtde) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}

/**Storage of annotation classnames in class */
class GatherAnnotationClassnames{
    /**Collected annotation classnames*/
    protected static Vector<ResultEditor.AnnotationClasses.AnnotatedClass> annotationClassnames
            = new Vector<ResultEditor.AnnotationClasses.AnnotatedClass>();

    /**Empty the hashtable which stores all annotation classnames.*/
    public void removeAllElements(){
        annotationClassnames.clear();
    }

    /**Try to add a new annotation class name into list if it isn't existing in the list yet.*/
    public void addElement(String annotationClassname, String absouteFilename){
        if(!isRepetitive(annotationClassname))
            annotationClassnames.add( new ResultEditor.AnnotationClasses.AnnotatedClass(
                    annotationClassname, null, absouteFilename, true, false) );
    }

    /**check the annotation class name in the list and return true if it has
     * exsited in the list.*/
    private boolean isRepetitive(String annotationClassname){
        if ( annotationClassnames == null )
            return false;
        for( ResultEditor.AnnotationClasses.AnnotatedClass annotatedclass : annotationClassnames){
            if ( annotatedclass == null )
                continue;
            if ( annotatedclass.annotatedClassName.trim().compareTo(annotationClassname.trim()) == 0 )
                return true;
        }
        return false;
    }

    /**retuan all stored annotation classname*/
    public Vector<ResultEditor.AnnotationClasses.AnnotatedClass> getAllElements(){
        return annotationClassnames;
    }

    
}